#include "Serialize.h"
#include <fstream>
void teststring();
void teststl();
void testselftype();
void teststack();
void testbasic();
void testqueue();
void testvecvec();
void handleMsg(const Serializer::ErrorMsg& msg){
    printf("errCode: %d\n",msg.errCode);
    printf("errMsg: %s\n", msg.errMsg.c_str());
    printf("wantedType: %s\n", msg.wantedType.c_str());
    printf("realType: %s\n",msg.realType.c_str());
    printf("errPos: %d\n",msg.errPos);
}
void testset();
void testmap();
void testunordered_set();
void testunordered_map();
int main()
{
    getAllEnumTypeString();
}
void testunordered_map()
{
    std::unordered_map<int, int> m{ {1,2},{2,3} };
    Serializer sr;
    sr.Serialize(m);
    std::unordered_map<int, int> m1;
    sr.DeSerialize(m1);
    for (auto& item : m1) {
        printf("%d %d\n", item.first, item.second);
    }
}
void testunordered_set()
{
    std::unordered_set<int> s{ 1,4,5,6 };
    Serializer sr;
    sr.Serialize(s);
    std::unordered_set<int> s1;
    sr.DeSerialize(s1);
    for (auto i : s1) {
        printf("%d ", i);
    }
}
void testmap()
{
    std::map<int, int> m{ {1,2},{2,3} };
    Serializer sr;
    sr.Serialize(m);
    std::map<int, int> m1;
    sr.DeSerialize(m1);
    for (auto& item : m1) {
        printf("%d %d\n", item.first, item.second);
    }
}
void testset() {
    std::set<int> s{ 1,2,4,5,6 };
    Serializer sr;
    sr.Serialize(s);
    std::set<int> s1;
    sr.DeSerialize(s1);
    for (auto i : s1) {
        printf("%d ", i);
    }
}
void testbasic()
{
    int a=4;
    float b = 1.5;
    double c = 3.1456;
    Serializer sr;
    sr.Serialize(a,b,c);
    std::ofstream fout("data.bin");
    if (!fout) return;
    sr.Save(fout);
    fout.close();
    sr.Clear();
    std::ifstream fin("data.bin");
    if (!fin) return;
    sr.Load(fin);
    fin.close();
    int a1;
    float b1;
    double c1;
    if (!sr.DeSerialize(a1,c1,b1)){
        handleMsg(sr.lastError);
    }
    printf("%d, %f, %f\n",a1,b1,c1);

    sr.Clear();
}
void testqueue()
{
    std::queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);
    Serializer sr;
    sr.Serialize(q);
    std::queue<int> q1;
    if (!sr.DeSerialize(q1)){
        handleMsg(sr.lastError);
    }
    while (!q1.empty()){
        printf("%d ",q1.front());
        q1.pop();
    }
}
void teststack(){
    std::stack<int> d;
    d.push(1);
    d.push(10);
    d.push(3);
    Serializer sr;
    sr.Serialize(d);
    std::stack<int> d1;
    if (!sr.DeSerialize(d1)){
        handleMsg(sr.lastError);
    }
    while (!d1.empty()){
        int i = d1.top();
        std::cout<<i<<" ";
        d1.pop();
    }
    std::cout<<sr.GetByteStream();
}
void teststring(){
    std::string s("hello world\n");
    Serializer sr;
    sr.Serialize(s);
    std::string s1;
    sr.DeSerialize(s1);
    std::cout<<sr.GetByteStream();
    std::ofstream fout("data.bin");
    if (!fout) return;
    sr.Save(fout);
    fout.close();
    sr.Clear();
    std::ifstream fin("data.bin");
    if (!fin) return;
    sr.Load(fin);
    sr.Save(std::cout);
    fin.close();
}
void teststl(){
    std::stack<int> a;
    auto typestr = getAllTypeString();
    std::vector<int> vec{1,2,4,6,7};
    Serializer sr;
    sr.Serialize(vec);
    std::vector<int> vec1;
    sr.DeSerialize(vec1);
    for (auto& i:vec1){
        std::cout<<i<<" ";
    }
    printf("\n");
    sr.Clear();

    std::list<int> lst{34,33,65,342};
    sr.Serialize(lst);
    std::list<int> lst1;
    sr.DeSerialize(lst1);
    for (auto& i : lst1){
        std::cout<<i<<" ";
    }
}
void testvecvec()
{
    std::vector<std::vector<int>> vec;
    vec.resize(2);
    for (auto&v: vec){
        v.resize(2,3);
    }
    Serializer sr;
    sr.Serialize(vec);

    std::vector<std::vector<int>> vec1;
    if (!sr.DeSerialize(vec1)){
        handleMsg(sr.lastError);
    }
    int a = 1;
}
class A{
    int x;
public:
    
    float y;
    std::vector<int> v;
    FRIEND_BYTESTREAM(A);
public:
    A(){}
    A(int _x, float _y, const std::vector<int>& _v):x(_x),y(_y),v(_v){}
    int X()const{return x;}
    void print()const{
        printf("x: %d, y: %f v: ",x,y);
        for (auto& i:v){
            printf("%i, ",i);
        }
        printf("\n");
    }
};

SERIALIZE_MEMBER(A,x,y,v);


void testselftype()
{
    std::vector<A> vec={{1,2.,{3,4}},{3,4.5,{5,6}}};
    Serializer sr;
    sr.Serialize(vec);
    std::vector<A> vec1;
    std::vector<int> a;
    if (!sr.DeSerialize(vec1)){
        handleMsg(sr.lastError);
    }
    for (auto& item:vec1){
        item.print();
    }
}